java泛型通配符 | 您所在的位置:网站首页 › extend pets › java泛型通配符 |
泛型 generics 协变 co-variant 逆变 Contra-variance 通配符类型 wildcard type 数组是协变的我们可以把一个dog的数组,赋值给Pet数组,因为Pet是Dog的基类。 Dog[] dogs = { new Dog() }; Pet[] pets = dogs;在pets这里,他已经不知道数组里的内容是Dog了,他可能会执行如下操作。 pets[0] = new Cat();这个时候编译是没问题的,但是运行会报错,抛出ArrayStoreException java的数组是协变的(简单说可以把子类数组赋给父类),但是这是不安全的,可能会引起运行时问题。 java泛型java1.5版本引入了泛型概念,由于数组协变带来了不安全,所以泛型设计的时候是不支持协变的,这样把运行时的问题提早到了编译时,提高了代码的安全性。 List dogs = new ArrayList(); List pet = dogs; // This line does not compile现在List和List两者是不同的类型,没有办法直接赋值,虽然保护了安全性,但是带来了新的问题。如下方法是给List准备的,但是List却不能使用,这多少有点违反直觉,毕竟Dog是Pet的子类。 public void feed(List pet){ }基于这个问题,出现了extend通配符 extend通配符使用? extends Pet就可以解决上述问题。这样似乎又变成协变的了。? extends Pet表示这里有个类型,他一定是Pet的子类,但是具体是什么类型我们不关心。 public void feed(List pets){ }协变的话,会不会产生数组的那种问题呢?,试试看如下代码 public void feed(List pets){ pets.add(new Cat()); }编译时直接报错了 对于的出现了super通配符,他保证这个类是Pet的父类,只允许写,不允许读。 List pets = new ArrayList(); List contravariantList = pets; Pet pet = contravariantList.get(0); // This does not compile. contravariantList.add(new Pet()); // OK 总结这就是目前java的通配符机制 extend通配符要求是X的子类只允许读,不允许写super通配符要求是X的父类只允许写,不允许读 refhttps://advancedweb.hu/using-java-generics-to-express-variance-of-collections-and-functions/ |
CopyRight 2018-2019 实验室设备网 版权所有 |